import { useState, useRef, useEffect } from 'react';
import { motion } from 'framer-motion';
import { toast } from 'sonner';

interface ChatMessage {
  id: string;
  type: 'user' | 'assistant';
  text: string;
  timestamp: Date;
}

export default function VoiceChat() {
  const [isRecording, setIsRecording] = useState(false);
  const [isProcessing, setIsProcessing] = useState(false);
  const [messages, setMessages] = useState<ChatMessage[]>([]);
  const [systemPrompt, setSystemPrompt] = useState('You are chatting with me, your name is xiaoxi. Only reply in English.');
  const [userPrompt, setUserPrompt] = useState('');
  const [audioUrl, setAudioUrl] = useState<string | null>(null);
  
  const audioRef = useRef<HTMLAudioElement>(null);
  const wsRef = useRef<WebSocket | null>(null);

  // 添加消息到聊天记录
  const addMessage = (type: 'user' | 'assistant', text: string) => {
    const newMessage: ChatMessage = {
      id: Date.now().toString(),
      type,
      text,
      timestamp: new Date()
    };
    setMessages(prev => [...prev, newMessage]);
  };

  // 播放音频
  const playAudio = (audioData: string) => {
    try {
      const audioBlob = new Blob([Uint8Array.from(atob(audioData), c => c.charCodeAt(0))], {
        type: 'audio/wav'
      });
      const url = URL.createObjectURL(audioBlob);
      setAudioUrl(url);
      
      if (audioRef.current) {
        audioRef.current.src = url;
        audioRef.current.play();
      }
    } catch (error) {
      console.error('音频播放失败:', error);
      toast.error('音频播放失败');
    }
  };

  // 开始语音对话
  const startVoiceChat = async () => {
    if (!userPrompt.trim()) {
      toast.error('请输入对话内容');
      return;
    }

    setIsProcessing(true);
    addMessage('user', userPrompt);

    try {
      const response = await fetch('http://localhost:8000/api/chat', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          system_prompt: systemPrompt,
          user_prompt: userPrompt
        }),
      });

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      const data = await response.json();
      
      if (data.success) {
        addMessage('assistant', data.message);
        
        if (data.audio_data) {
          playAudio(data.audio_data);
        }
        
        setUserPrompt('');
        toast.success('对话完成');
      } else {
        toast.error('对话失败');
      }
    } catch (error) {
      console.error('对话请求失败:', error);
      toast.error('对话请求失败');
    } finally {
      setIsProcessing(false);
    }
  };

  // WebSocket语音聊天
  const startWebSocketChat = () => {
    if (wsRef.current?.readyState === WebSocket.OPEN) {
      toast.error('WebSocket连接已存在');
      return;
    }

    setIsRecording(true);
    toast.info('正在连接语音服务...');

    wsRef.current = new WebSocket('ws://localhost:8000/ws/voice-chat');

    wsRef.current.onopen = () => {
      toast.success('语音服务连接成功，请开始说话');
    };

    wsRef.current.onmessage = (event) => {
      const data = JSON.parse(event.data);
      
      switch (data.type) {
        case 'status':
          toast.info(data.message);
          break;
        case 'recognition':
          addMessage('user', data.text);
          toast.success(`识别结果: ${data.text}`);
          break;
        case 'gpt_response':
          addMessage('assistant', data.text);
          toast.success('AI回复已生成');
          break;
        case 'audio':
          playAudio(data.data);
          break;
        case 'complete':
          setIsRecording(false);
          toast.success('语音对话完成');
          break;
        case 'error':
          setIsRecording(false);
          toast.error(data.message);
          break;
      }
    };

    wsRef.current.onerror = (error) => {
      console.error('WebSocket错误:', error);
      setIsRecording(false);
      toast.error('WebSocket连接错误');
    };

    wsRef.current.onclose = () => {
      setIsRecording(false);
      toast.info('WebSocket连接已关闭');
    };
  };

  // 停止WebSocket聊天
  const stopWebSocketChat = () => {
    if (wsRef.current) {
      wsRef.current.close();
      wsRef.current = null;
    }
    setIsRecording(false);
  };

  // 清理音频URL
  useEffect(() => {
    return () => {
      if (audioUrl) {
        URL.revokeObjectURL(audioUrl);
      }
    };
  }, [audioUrl]);

  return (
    <div className="min-h-screen bg-gradient-to-b from-blue-50 to-white py-8 px-4">
      <div className="max-w-4xl mx-auto">
        {/* 页面标题 */}
        <motion.div
          initial={{ opacity: 0, y: -20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.5 }}
          className="text-center mb-8"
        >
          <h1 className="text-4xl font-bold text-gray-900 mb-4">语音对话系统</h1>
          <p className="text-gray-600">与AI助手进行实时语音对话</p>
        </motion.div>

        <div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
          {/* 左侧：文本对话 */}
          <motion.div
            initial={{ opacity: 0, x: -20 }}
            animate={{ opacity: 1, x: 0 }}
            transition={{ duration: 0.5, delay: 0.2 }}
            className="bg-white rounded-xl shadow-lg p-6"
          >
            <h2 className="text-2xl font-semibold mb-4">文本对话</h2>
            
            {/* 系统提示词 */}
            <div className="mb-4">
              <label className="block text-sm font-medium text-gray-700 mb-2">
                系统提示词
              </label>
              <textarea
                value={systemPrompt}
                onChange={(e) => setSystemPrompt(e.target.value)}
                className="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
                rows={3}
                placeholder="输入系统提示词..."
              />
            </div>

            {/* 用户输入 */}
            <div className="mb-4">
              <label className="block text-sm font-medium text-gray-700 mb-2">
                对话内容
              </label>
              <textarea
                value={userPrompt}
                onChange={(e) => setUserPrompt(e.target.value)}
                className="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
                rows={4}
                placeholder="输入你想说的话..."
              />
            </div>

            {/* 发送按钮 */}
            <button
              onClick={startVoiceChat}
              disabled={isProcessing || !userPrompt.trim()}
              className="w-full bg-blue-600 text-white py-3 px-6 rounded-lg font-medium hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors"
            >
              {isProcessing ? '处理中...' : '发送对话'}
            </button>
          </motion.div>

          {/* 右侧：语音对话 */}
          <motion.div
            initial={{ opacity: 0, x: 20 }}
            animate={{ opacity: 1, x: 0 }}
            transition={{ duration: 0.5, delay: 0.4 }}
            className="bg-white rounded-xl shadow-lg p-6"
          >
            <h2 className="text-2xl font-semibold mb-4">语音对话</h2>
            
            <div className="text-center mb-6">
              <div className={`w-24 h-24 mx-auto rounded-full flex items-center justify-center text-white text-2xl font-bold mb-4 ${
                isRecording ? 'bg-red-500 animate-pulse' : 'bg-gray-400'
              }`}>
                {isRecording ? '🎤' : '🎙️'}
              </div>
              <p className="text-gray-600">
                {isRecording ? '正在录音，请说话...' : '点击开始语音对话'}
              </p>
            </div>

            <div className="space-y-3">
              <button
                onClick={startWebSocketChat}
                disabled={isRecording}
                className="w-full bg-green-600 text-white py-3 px-6 rounded-lg font-medium hover:bg-green-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors"
              >
                开始语音对话
              </button>
              
              <button
                onClick={stopWebSocketChat}
                disabled={!isRecording}
                className="w-full bg-red-600 text-white py-3 px-6 rounded-lg font-medium hover:bg-red-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors"
              >
                停止语音对话
              </button>
            </div>
          </motion.div>
        </div>

        {/* 聊天记录 */}
        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.5, delay: 0.6 }}
          className="mt-8 bg-white rounded-xl shadow-lg p-6"
        >
          <h2 className="text-2xl font-semibold mb-4">对话记录</h2>
          
          <div className="space-y-4 max-h-96 overflow-y-auto">
            {messages.length === 0 ? (
              <p className="text-gray-500 text-center py-8">暂无对话记录</p>
            ) : (
              messages.map((message) => (
                <div
                  key={message.id}
                  className={`flex ${message.type === 'user' ? 'justify-end' : 'justify-start'}`}
                >
                  <div
                    className={`max-w-xs lg:max-w-md px-4 py-2 rounded-lg ${
                      message.type === 'user'
                        ? 'bg-blue-600 text-white'
                        : 'bg-gray-200 text-gray-800'
                    }`}
                  >
                    <p className="text-sm">{message.text}</p>
                    <p className="text-xs opacity-70 mt-1">
                      {message.timestamp.toLocaleTimeString()}
                    </p>
                  </div>
                </div>
              ))
            )}
          </div>
        </motion.div>

        {/* 音频播放器 */}
        <audio ref={audioRef} className="hidden" />
      </div>
    </div>
  );
} 